package com.fuyu.common.utils;

import com.alibaba.fastjson2.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fuyu.common.model.TokenUserInfo;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;


@Slf4j
public class JwtUtil {

    private static final String userInfoKey = "userInfo";

    private static final String secret = "hello";


    /**
     * 根据用户密码,账号生成token
     */
    public static String createToken(TokenUserInfo user) {

        String token = "";
        try {
            //过期时间
            Date expireDate = new Date(new Date().getTime() + 60L * 1000 * 60 * 24 * 365);
            //秘钥及加密算法
            Algorithm algorithm = Algorithm.HMAC256(secret);

            String userInfo = JSON.toJSONString(user);

            //携带id，账号信息，生成签名
            token = JWT.create()
                    .withClaim(userInfoKey, userInfo)
                    .withClaim("id", user.getUserId())
                    .withClaim("username", user.getUsername())
                    .withExpiresAt(expireDate)
                    .sign(algorithm);

            return token;
        } catch (Exception e) {
            log.error("\ntoken生成失败{}", e.getMessage());
            throw new IllegalStateException("token生成失败");
        }
    }

    /**
     * 验证token是否有效
     */
    public static boolean verify(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm).build();
            verifier.verify(token);
            return true;
        } catch (Exception e) {
            throw new RuntimeException("token过期");
        }
    }


    public static DecodedJWT getDecodedJWT(String token) {
        DecodedJWT tokenInfo = JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
        return tokenInfo;
    }

    /**
     * 解析出token中的用户id
     */
    public static String getUserId(String token) {
        try {
            DecodedJWT tokenInfo = getDecodedJWT(token);
            Claim id = tokenInfo.getClaim("id");

            return id.asString();
        } catch (Exception e) {
            throw new IllegalStateException("解析出token中的用户id失败");
        }
    }
}
